﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Diagnostics;

namespace Master
{

    public class Road : Grid
    {
        /********************
         * PUBLIC FUNCTIONS *
         ********************/
        public Lane[] getLanes()
        {
            List<Lane> laneList = new List<Lane>();
            foreach (UIElement child in Children) if (child is Lane)
                laneList.Add((Lane) child);
            return laneList.ToArray();
        }

        public Lane getLeftLane()
        {
            int orientation = getLanes()[0].Orientation;
            switch (orientation)
            {
                case 0: return getLaneWithSmallestX();
                case 90: return getLaneWithSmallestY();
                case 180: return getLaneWithHighestX();
                case 270: return getLaneWithHighestY();
                default: throw new InvalidOperationException("Lane orientation is invalid");
            }
        }

        public Lane getRightLane()
        {
            int orientation = getLanes()[0].Orientation;
            switch (orientation)
            {
                case 0: return getLaneWithHighestX();
                case 90: return getLaneWithHighestY();
                case 180: return getLaneWithSmallestX();
                case 270: return getLaneWithSmallestY();
                default: throw new InvalidOperationException("Lane orientation is invalid");
            }
        }

        public Lane getLaneWithHighestX()
        {
            Lane xLane = null;
            foreach (Lane lane in getLanes())
                if (xLane == null || Toolkit.getPointRelativeToMap(xLane).X < Toolkit.getPointRelativeToMap(lane).X)
                    xLane = lane;
            return xLane;
        }

        public Lane getLaneWithSmallestX()
        {
            Lane xLane = null;
            foreach (Lane lane in getLanes())
                if (xLane == null || Toolkit.getPointRelativeToMap(xLane).X > Toolkit.getPointRelativeToMap(lane).X)
                    xLane = lane;
            return xLane;
        }

        public Lane getLaneWithHighestY()
        {
            Lane yLane = null;
            foreach (Lane lane in getLanes())
                if (yLane == null || Toolkit.getPointRelativeToMap(yLane).Y < Toolkit.getPointRelativeToMap(lane).Y)
                    yLane = lane;
            return yLane;
        }

        public Lane getLaneWithSmallestY()
        {
            Lane yLane = null;
            foreach (Lane lane in getLanes())
                if (yLane == null || Toolkit.getPointRelativeToMap(yLane).Y > Toolkit.getPointRelativeToMap(lane).Y)
                    yLane = lane;
            return yLane;
        }

        public Lane getLaneAtX(int x)
        {
            foreach (Lane lane in getLanes())
                if (Toolkit.elementIsAtX(lane, x))
                    return lane;
            return null;
        }

        public Lane getLaneAtY(int y)
        {
            foreach (Lane lane in getLanes())
                if (Toolkit.elementIsAtY(lane, y))
                    return lane;
            return null;
        }
    }
}
